using System;
using System.Collections.Generic;
using System.Web.Security;
using System.Web.Script.Serialization;
using System.Linq;
using System.Web.Mvc;
using System.Web.UI;
using System.IO;

using MvcCmsSocial.Service;
using MvcCms.Data;
using MvcCms.Service.Cache;
using MvcCms.Service.Validation;
using MvcCms.Service.Logging;
using MvcCms.Service;
using MvcCms.Service.Code.Wiki;
using WikiPlex;
using WikiPlex.Formatting;
using Microsoft.Practices.ServiceLocation;
using MvcCmsSocial.Models;

namespace MvcCmsSocial.Controllers
{
    public class MvcCmsSocialAjaxController : MvcCms.Service.Code.BaseClasses.MvcCmsControllerBase
    {
        #region Constructors
        private readonly IFileStore _fileStore;
        private readonly IWikiEngine _wikiEngine;
        private readonly ICacheService _cacheService;
        private readonly IAccountService _accountService;
        private readonly ISocialService _socialService;
        public MvcCmsSocialAjaxController(IWikiEngine wikiEngine, ICacheService cacheService, IAccountService accountService, ISocialService socialService, ICmsService cmsService)
        {
            _cacheService = cacheService;
            _fileStore = new DiskFileStore(cacheService);
            _wikiEngine = wikiEngine;
            _accountService = accountService;
            _socialService = socialService;
        }
        #endregion

        private MacroFormatter GetFormatter()
        {
            var siteRenderers = new IRenderer[]
            {
                new TitleLinkRenderer(Url),
                new TextColorRenderer() ,
                new TextSizeRenderer(),
                new AnyStyleRenderer(),
            };
            IEnumerable<IRenderer> allRenderers = Renderers.All.Union(siteRenderers);
            return new MacroFormatter(allRenderers);
        }

        [Authorize]
        [AcceptVerbs(HttpVerbs.Post)]
        [OutputCache(Location = OutputCacheLocation.None)]
        public string GetAboutMeSource()
        {
            var socialData = _socialService.GetUser(_accountService.GetUserName()).SocialData.FirstOrDefault();
            if (socialData != null)
            {
                return socialData.AboutMe;
            }
            return string.Empty;
        }

        [Authorize]
        [AcceptVerbs(HttpVerbs.Post)]
        public string AsyncUpload()
        {
            //for this to work with swfupload requires some global.asax hacks (see notes in beginrequest)
            //may not be suitable for all environments
            var user = _accountService.GetUser();
            var newFileName = _fileStore.SaveUploadedFile(Request.Files[0]);
            bool makeProfile = false;
            var currentProfilePic = _socialService.ListSocialImages(user.UserID).Where(pic => pic.IsProfilePic).FirstOrDefault();
            if (currentProfilePic == null) { makeProfile = true; }
            var newImage = new SocialImage
            {
                User = user,
                ImageFriendlyName = Request.Files[0].FileName,
                ImageName = newFileName,
                IsProfilePic = makeProfile
            };

            if (_socialService.CreateSocialImage(newImage))
            {

                return newFileName;
            }
            return "There was a problem saving your image.";
        }

        [AcceptVerbs(HttpVerbs.Post)]
        [OutputCache(Location = OutputCacheLocation.None)]
        [ValidateInput(false)]
        public string GetAboutMePreview(string source)
        {
            return _wikiEngine.Render(source, GetFormatter());
        }

        [Authorize]
        public JsonResult ShareOnWall(string data)
        {
            try
            {
                var messageToCreate = new JavaScriptSerializer().Deserialize<SocialMessage>(data);
                var dTOCreatedMessage = _socialService.CreateSocialMessage(messageToCreate, "Wall");
                if (dTOCreatedMessage != null)
                {
                    dTOCreatedMessage.Body = dTOCreatedMessage.Body.ConvertUrlsToLinks();
                    return Json(dTOCreatedMessage);
                }
                return Json(new { error = "There was a problem creating your message." });
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(ex.Message, ex);
                return Json(new { error = ex.Message });
            }
        }

        [Authorize]
        public JsonResult YouLike(string data)
        {
            try
            {
                var likeToCreate = new JavaScriptSerializer().Deserialize<SocialLike>(data);
                if (_socialService.CreateSocialLike(likeToCreate))
                {
                    return Json(new { status = "Success" });
                }
                return Json(new { error = "There was a problem creating your like." });
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(ex.Message, ex);
                return Json(new { error = ex.Message });
            }
        }

        [Authorize]
        public JsonResult DeleteImage(string data)
        {
            try
            {
                var user = _accountService.GetUser();
                var imageToDelete = new JavaScriptSerializer().Deserialize<SocialImage>(data);
                string foldername = _cacheService.GetCurrentPortal().Name.ToUrlFormat();
                string path = Server.MapPath("~/Uploadedimages/" + foldername + "/Profiles");
                string thumbPath = Server.MapPath("~/Uploadedimages/" + foldername + "/Profiles/thumbs");
                string filePath = Path.Combine(path, Path.GetFileName(imageToDelete.ImageName));
                if (System.IO.File.Exists(filePath))
                {
                    SocialImage image;
                    if (Roles.IsUserInRole("Admin"))
                    {
                        image = _socialService.GetSocialImage(imageToDelete.ImageName);
                    }
                    else
                    {
                        image = _socialService.GetSocialImage(imageToDelete.ImageName, user.UserID);
                    }
                    if (image != null)
                    {
                        if (!image.IsProfilePic || Roles.IsUserInRole("Admin"))
                        {
                            if (_socialService.DeleteSocialImage(image))
                            {
                                System.IO.File.Delete(filePath);
                                filePath = Path.Combine(thumbPath, Path.GetFileName(imageToDelete.ImageName));
                                System.IO.File.Delete(filePath);
                                return Json(new { result = "success" });
                            }
                        }
                        else
                        {
                            return Json(new { error = "Can't delete current profile picture." });
                        }
                    }
                }
                return Json(new { error = "File doesnot exist" });
            }
            catch (UnauthorizedAccessException ex)
            {
                return Json(new { error = "You do not have required permission for this operation " + ex.Message });
            }
            catch (IOException exIO)
            {
                return Json(new { error = "File in use " + exIO.Message });
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(ex.Message, ex);
                return Json(new { error = ex.Message });
            }
        }

        [Authorize]
        public JsonResult SetAsProfile(string data)
        {
            try
            {
                var imageToDelete = new JavaScriptSerializer().Deserialize<SocialImage>(data);
                var user = _accountService.GetUser();
                SocialImage image;
                if (Roles.IsUserInRole("Admin"))
                {
                    image = _socialService.GetSocialImage(imageToDelete.ImageName);
                }
                else
                {
                    image = _socialService.GetSocialImage(imageToDelete.ImageName, user.UserID);
                }
                image.IsProfilePic = true;
                image.User = user;
                _socialService.EditSocialImage(image);
                return Json(new { result = "success" });
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(ex.Message, ex);
                return Json(new { error = ex.Message });
            }
        }
    }
}
